﻿using EEM.Helpers;
using EEM.LocalModels;
using EEM.Models;
using EEM.MyControls;
using HZH_Controls.Controls;
using Newtonsoft.Json;
using System;
using System.Data;
using System.Reflection;
using System.Text;
using System.Threading.Channels;
using ZedGraph;

namespace EEM.Pages
{
    public partial class PgMonitor : Form
    {
        public PgMonitor()
        {
            InitializeComponent();
            FrmMain.FrmMainEvent += loadBottomItem;
        }

        private void PgMonitor_Load(object sender, EventArgs e)
        {
            loadAsideItem();
            loadBottomItem(sender, e);
            loadLine();
        }

        int CurrID = 1;
        string CurrName = "客厅";
        private void loadAsideItem()
        {
            List<AreaInfo> areaList = CommonHelper.areaList;
            if (areaList.Count <= 0) return;

            List<ListEntity> list = new List<ListEntity>();

            foreach (AreaInfo area in areaList)
            {
                ListEntity item = new ListEntity();
                item.Title = area.AreaName;
                item.ID = area.AreaId.ToString();
                list.Add(item);
            }
            ucListExt1.SetList(list);
            ucListExt1.ItemClick += clickFunc;
        }

        void loadBottomItem(object sender, EventArgs e)
        {
            //213, 119
            flowLayoutPanel.Controls.Clear();
            using (EEMContext db = new EEMContext())
            {
                List<AreaDatalnfo> infos = db.AreaDatalnfos.ToList();
                List<AreaItem> areaItems = new List<AreaItem>();

                foreach (AreaDatalnfo info in infos)
                {
                    string name = CommonHelper.areaList.Single(a => a.AreaId == info.Areald).AreaName;
                    AreaItem areaItem = new AreaItem()
                    {
                        Title = name,
                        Temperature = info.Temperature,
                        Humidity = info.Humidity
                    };
                    areaItems.Add(areaItem);

                    if (CommonHelper.areaList[0].AreaId == info.Areald)
                    {
                        setDataToUControl<AreaDatalnfo>(info);
                    }
                }

                flowLayoutPanel.Controls.AddRange(areaItems.ToArray());
            }
        }

        private void clickFunc(UCListItemExt item)
        {
            ListEntity data = item.DataSource;
            CurrID = data.ID.GetInt();
            CurrName = data.Title;
            //展示数据
            showData(CurrID);
            //重新加载曲线
            loadLine();
        }

        private void showData(int id)
        {
            var dicData = CommonHelper.dicDatas.SingleOrDefault(d => d.Key == id).Value;
            setDataToUControl<AreaData>(dicData);
        }

        private void setDataToUControl<T>(T obj)
        {
            Type type = typeof(T);

            PropertyInfo? tempInfo = type.GetProperty("Temperature");
            decimal temp = (decimal)tempInfo.GetValue(obj);
            temperNum.Value = temp.ToString();
            ucThermometer.Value = temp;
            ColorStatus info1 = matchStatus(CommonHelper.tempColorPath, temp);
            labTemper.Text = info1.Title;
            temperLight.FillColor = info1.ColorRGB;
            temperLight.RectColor = info1.ColorRGB;

            PropertyInfo? humInfo = type.GetProperty("Humidity");
            decimal humidity = (int)humInfo.GetValue(obj);
            humNum.Value = humidity.ToString();
            ucMeter.Value = humidity;
            ColorStatus info2 = matchStatus(CommonHelper.humColorPath, humidity);
            labHum.Text = info2.Title;
            humLight.FillColor = info2.ColorRGB;
            humLight.RectColor = info2.ColorRGB;
        }

        private ColorStatus matchStatus(string path, decimal num)
        {
            string info = File.ReadAllText(path, Encoding.UTF8);
            var list = JsonConvert.DeserializeObject<List<ColorStatus>>(info);

            ColorStatus target = null;
            target = list.Single(new Func<ColorStatus, bool>(item =>
            {
                string[] numStrs = item.Range.Split(";");

                string min = "", max = "";

                min = numStrs[0];
                max = numStrs[1];

                bool falg = false;
                if (min.GetInt() <= num && num < max.GetInt())
                {
                    falg = true;
                }
                else if (min.Equals("-") && num < max.GetInt())
                {
                    falg = true;
                }
                else if (max.Equals("+") && num >= min.GetInt())
                {
                    falg = true;
                }

                return falg;
            }));
            if (target == null) return null;

            int[] arr = target.Color.Split(",").Select(c => c.GetInt()).ToArray();
            target.ColorRGB = Color.FromArgb(arr[0], arr[1], arr[2]);
            return target;
        }



        #region 曲线相关
        private List<LineChannel> channels = new List<LineChannel>();   //所有的曲线
        private int tickStart = Environment.TickCount;     // 起始时间以毫秒为单位
        LineChannel line1 = new LineChannel(1111, 1, "温度(℃)", "℃", true, Color.Red, 1);
        LineChannel line2 = new LineChannel(2222, 2, "湿度(%)", "%", true, Color.Green, 1);
        LineChannel line3 = new LineChannel(3333, 3, "CO2(ppm)", "ppm", true, Color.Gray, 1);
        GraphPane myPane = null;


        void loadLine()
        {
            timer.Stop();
            myPane?.CurveList.Clear();
            channels.Clear();
            runLine();
        }


        void runLine()
        {
            timer.Interval = 1000;
            timer.Enabled = true; //timer可用


            channels.Add(line1);
            channels.Add(line2);
            channels.Add(line3);

            myPane = zedGraphControl.GraphPane;
            myPane.XAxis.Scale.IsUseTenPower = false;
            myPane.XAxis.MajorGrid.IsVisible = true;
            myPane.XAxis.Scale.Min = 0; //X轴最小值0
            myPane.XAxis.Scale.Max = 30; //X轴最大30
            myPane.XAxis.Scale.MinorStep = 1;//X轴小步长1,也就是小间隔
            myPane.XAxis.Scale.MajorStep = 5;//X轴大步长为5，也就是显示文字的大间隔

            myPane.Title.Text = CurrName;
            myPane.XAxis.Title.Text = "时间";
            myPane.YAxis.Title.Text = null;



            for (int i = 0; i < channels.Count; i++)
            {
                RollingPointPairList listItem = new RollingPointPairList(1200);
                myPane.AddCurve(channels[i].Name, listItem, channels[i].LineColor);
            }
            zedGraphControl.AxisChange();

            timer.Start(); //开始
        }

        private void timer_Tick(object sender, EventArgs e)
        {

            //取Graph第一个曲线，也就是第一步:在GraphPane.CurveList集合中查找CurveItem
            LineItem curve1 = myPane.CurveList[0] as LineItem;
            LineItem curve2 = myPane.CurveList[1] as LineItem;
            LineItem curve3 = myPane.CurveList[2] as LineItem;
            if (curve1 == null | curve2 == null | curve3 == null)
            {
                return;
            }
            //第二步:在CurveItem中访问PointPairList(或者其它的IPointList)，根据自己的需要增加新数据或修改已存在的数据
            IPointListEdit list1 = curve1.Points as IPointListEdit;
            IPointListEdit list2 = curve2.Points as IPointListEdit;
            IPointListEdit list3 = curve3.Points as IPointListEdit;

            if (list1 == null | list2 == null | list3 == null)
            {
                return;
            }
            // 时间用秒表示
            double time = (Environment.TickCount - tickStart) / 1000.0;

            if (CommonHelper.dicDatas.Count <= 0) return;

            double rdm1 = (double)CommonHelper.dicDatas[CurrID].Temperature;
            double rdm2 = CommonHelper.dicDatas[CurrID].Humidity;
            double rdm3 = CommonHelper.dicDatas[CurrID].C02density;

            list1.Add(time, rdm1);
            list2.Add(time, rdm2);
            list3.Add(time, rdm3);

            //Console.WriteLine(time.ToString());
            Scale xScale = myPane.XAxis.Scale;
            if (time > xScale.Max - xScale.MajorStep)
            {
                xScale.Max = time + xScale.MajorStep;
                xScale.Min = xScale.Max - 30.0;
            }

            //第三步:调用ZedGraphControl.AxisChange()方法更新X和Y轴的范围
            zedGraphControl.AxisChange();

            //第四步:调用Form.Invalidate()方法更新图表
            zedGraphControl.Invalidate();
        }
        #endregion
    }
}
